﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once

#include <QDialog.h>

#include "GcmpUiQtImpl.h"

#include "IActionInputDialog.h"
#include "GcmpGuiQt.h"
#include "vector"
#include "IControl.h"
#include "IControlDefinition.h"
#include "IUiViewEventHandler.h"

class QWidget;
class QVBoxLayout;
class QHBoxLayout;

namespace gcmp
{
    class IAction;
    class ActionInputEvent;
    class IActionInputEvent;
    class ILineEditEventHandler;
    class ICheckBoxGroupEventHandler;
    class IRadioButtonGroupEventHandler;
    class IComboBoxEventHandler;
}

class GmTitleBar;
class ActionBarDialog;


/// \brief ActionInputDialog是使用控件定义的方式创建控件的新参数对话框
class GCMP_GUI_QT_EXPORT ActionBarDialog : public QDialog, public gcmp::IActionInputDialog
{
    Q_OBJECT

public:
    /// \brief 构造函数
    ///
    /// \param parent 参数对话框的父控件    
    ActionBarDialog(QWidget *parent = 0);

    /// \brief 析构函数
    virtual ~ActionBarDialog();

    void ResetPosition();

    /// \brief 清理资源，ActionBarDialogReference析构时调用
    void DestroyDialog();

private slots:    
    void OnEditEnterPressed();

protected:
    virtual void leaveEvent(QEvent *) Q_DECL_OVERRIDE;
    virtual void keyPressEvent(QKeyEvent *) Q_DECL_OVERRIDE;//重载键盘消息，避免esc键被对话框基类处理成退出消息
    //virtual void showEvent(QShowEvent *) Q_DECL_OVERRIDE;
    virtual void moveEvent(QMoveEvent *) Q_DECL_OVERRIDE;

    virtual void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
    virtual void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
    virtual void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;

    virtual bool focusNextPrevChild(bool next) Q_DECL_OVERRIDE;
private:
    //保存/恢复窗口状态

    void Clear();
    void SetFocusToCurrentView();

    bool eventFilter(QObject *object, QEvent *event);

    // create a specific control according to the given control-define
    template<typename ControlType, typename ControlDefinitionType>
    ControlType* AddControl(gcmp::OwnerPtr<ControlDefinitionType> pControlDefinition);

    // create a specific control/group according to the given control-define
    template<typename ControlGroupType, typename ControlType, typename ControlGroupDefineType>
    gcmp::IControl* AddControlGroup(gcmp::OwnerPtr<ControlGroupDefineType> pControlGroupDefine, bool needAddSepartor);

    QHBoxLayout* GetDialogLayout() const { return m_pQHBoxLayout;  }
    void SetDialogLayout(QHBoxLayout* pLayout);

    // create a label control
    gcmp::IControl* AddLabel(const std::wstring& name, const std::wstring& caption, const std::wstring& tooltip);

    void onMoveRequested(const QPoint& cursorPos, const QPoint& offset);



public:
    /// \brief 初始化参数对话框，根据传入的参数创建对话框上的各种控件
    ///
    /// \param dlgCtrlDefines 控件定义数组
    void InitDlg(const std::wstring& title,std::vector<gcmp::OwnerPtr<gcmp::IControlDefinition>>&& dlgCtrlDefines, gcmp::IAction* pAction);

    /// \brief 设置参数对话框标题
    ///
    /// \param strTitle 标题文本
    void SetWindowTitle(const std::wstring& strTitle);
   
    virtual gcmp::IActionInputEvent* GetInputEvent() override;

    gcmp::IAction* GetAction();
private:
    //for move Dialog
    bool        m_isMoving;         //标记对话框是否正在被移动
    QPoint      m_movePosition;     //对话框的移动量

    QHBoxLayout* m_pQHBoxLayout;    //对话框容纳控件的布局
    std::vector<gcmp::WeakPtr<gcmp::IControl>> m_wpControls; // do not keep controls which are in a group (check box & radio button)

    gcmp::IAction*    m_pAction;
    gcmp::OwnerPtr<gcmp::ActionInputEvent>    m_inputEvent;
    std::vector<gcmp::OwnerPtr<gcmp::ILineEditEventHandler>>  m_lineEditHandler;
    std::vector<gcmp::OwnerPtr<gcmp::ICheckBoxGroupEventHandler>>  m_checkBoxGroupHandler;
    std::vector<gcmp::OwnerPtr<gcmp::IRadioButtonGroupEventHandler>>  m_radioButtonGroupHandler;
    std::vector<gcmp::OwnerPtr<gcmp::IComboBoxEventHandler>>  m_comboBoxHandler;
};

